<template>
  <div
    :id="uploadId"
    class="img-uplaod-container"
  >
    <draggable
      v-model="fileList"
      class="drag-img-list"
      v-bind="{group: uploadId, ghostClass: 'ghost', animation: 200}"
      :no-transition-on-drag="true"
    >
      <div
        v-for="(item) in fileList"
        :id="item.key"
        :key="item.key"
        :style="{width: width+'px', height: height+'px'}"
        :class="{uploading: item.status=='uploading', 'is-success': item.status=='success', 'is-diabled': disabled}"
        class="upload-file"
      >
        <img
          v-if="item.isImg"
          :src="item.previewPath"
        >
        <i
          v-else
          class="el-icon-files"
          style="font-size: 40px;color: #4ca1ff;"
          title="文件"
        />

        <el-progress
          v-if="item.status=='uploading'"
          :width="miniWidth*0.9"
          class="upload-progress"
          type="circle"
          :percentage="item.percent"
        />

        <label
          v-if="item.status=='success'"
          class="item-status"
        >
          <i class="el-icon-upload-success el-icon-check" />
        </label>

        <div
          class="uplaod-action"
          :style="{height: miniWidth / 4 + 'px'}"
        >
          <a
            :href="item.previewPath"
            target="blank"
          >
            <i
              class="el-icon-view"
              title="预览"
              :style="{'font-size': miniWidth/8+'px'}"
            />
          </a>
          <i
            v-if="isEdit && !disabled"
            class="el-icon-refresh"
            :title="'替换'"
            :style="{'font-size': miniWidth/8+'px'}"
            @click="handleEdit(item.key)"
          />
          <i
            v-if="isDelete && fileList.length > min && !disabled"
            class="el-icon-delete"
            :title="'删除'"
            :style="{'font-size': miniWidth/8+'px'}"
            @click="handleRemove(item.key)"
          />
        </div>
      </div>
    </draggable>

    <div
      v-show="(!isQiniu || (isQiniu && token)) && fileList.length < length && !disabled"
      class="el-upload el-upload--picture-card"
      :class="{'is-disabled': disabled}"
      :style="{width: width+'px', height: height+'px'}"
      @click.self="handleAdd"
    >
      <i
        class="el-icon-plus"
        :style="{fontSize:miniWidth/4+'px',marginTop: (-miniWidth/8)+'px', marginLeft: (-miniWidth/8)+'px'}"
        @click.self="handleAdd"
      />
      <!-- <input accept="image/*" v-if="multiple"  multiple ref="uploadInput" @change="handleChange" type="file" :style="{width: 0, height: 0}" name="files" class="el-upload__input upload-input">
      <input accept="image/*" v-else ref="uploadInput" @change="handleChange" type="file" :style="{width:0, height: 0}" name="files" class="el-upload__input upload-input"> -->
      <input
        v-if="multiple"
        ref="uploadInput"
        multiple
        type="file"
        :style="{width: 0, height: 0}"
        name="files"
        class="el-upload__input upload-input"
        accept=".jpg,.png,.jpeg,.xls,.xlsx,.doc,.docx,.ppt,.pptx,.pdf,.ofd"
        @change="handleChange"
      >
      <input
        v-else
        ref="uploadInput"
        type="file"
        :style="{width:0, height: 0}"
        name="files"
        class="el-upload__input upload-input"
        accept=".jpg,.png,.jpeg,.xls,.xlsx,.doc,.docx,.ppt,.pptx,.pdf,.ofd"
        @change="handleChange"
      >
    </div>
    <Model
      ref="formPreview"
      :visible="previewVisible"
      width="600px"
      form
      @on-close="previewVisible = false"
    >
      <img
        :src="previewUrl"
        alt=""
        style="display: block;width: 80%;margin: 0 auto;"
      >
      <template slot="action">
        <el-button
          size="mini"
          @click="previewVisible = false"
        >关闭</el-button>
      </template>
    </Model>
  </div>
</template>

<script>
// import Viewer from 'viewerjs'
import Draggable from 'vuedraggable'
import Model from './Model'
import { getToken } from '@/utils/auth'
// import * as qiniu from 'qiniu-js'
// require('viewerjs/dist/viewer.css')
export default {
  components: {
    Draggable,
    Model
  },
  props: {
    data: {
      type: Array,
      default: () => []
    },
    width: {
      type: Number,
      default: 100
    },
    height: {
      type: Number,
      default: 100
    },
    token: {
      type: String,
      default: ''
    },
    domain: {
      type: String,
      default: ''
    },
    multiple: {
      type: Boolean,
      default: false
    },
    length: {
      type: Number,
      default: 9
    },
    isQiniu: {
      type: Boolean,
      default: false
    },
    isDelete: {
      type: Boolean,
      default: false
    },
    min: {
      type: Number,
      default: 0
    },
    meitu: {
      type: Boolean,
      default: false
    },
    isEdit: {
      type: Boolean,
      default: false
    },
    action: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      previewVisible: false,
      previewUrl: '',
      fileList: this.data.map(item => {
        return {
          key: item.key
            ? item.key
            : new Date().getTime() + '_' + Math.ceil(Math.random() * 99999),
          Src: item.Src,
          isImg: item.isImg,
          percent: item.percent ? item.percent : 100,
          status: item.status ? item.status : 'success'
        }
      }),
      viewer: null,
      uploadId: 'upload_' + new Date().getTime(),
      editIndex: -1,
      meituIndex: -1
    }
  },
  computed: {
    miniWidth() {
      if (this.width > this.height) {
        return this.height
      } else {
        return this.width
      }
    }
  },
  watch: {
    data: {
      deep: true,
      handler(obj) {
        // console.log('fileList', obj)
        this.fileList = obj.map(item => {
          return {
            key: item.key
              ? item.key
              : new Date().getTime() + '_' + Math.ceil(Math.random() * 99999),
            Src: item.Src,
            isImg: item.isImg,
            percent: item.percent ? item.percent : 100,
            status: item.status ? item.status : 'success'
          }
        })
      }
    }
    // fileList: {
    //   deep: true,
    //   handler() {
    //     this.$emit('update:data', this.fileList)
    //   }
    // }
  },
  mounted() {
    // this.$emit('update:data', this.fileList)
  },
  methods: {
    handleChange() {
      const files = this.$refs.uploadInput.files
      for (let i = 0; i < files.length; i++) {
        const file = files[i]
        const reader = new FileReader()
        const key =
          new Date().getTime() + '_' + Math.ceil(Math.random() * 99999)
        reader.readAsDataURL(file)
        reader.onload = () => {
          if (this.editIndex >= 0) {
            this.$set(this.fileList, this.editIndex, {
              key,
              Src: reader.result,
              percent: 0,
              status: 'uploading'
            })
            this.editIndex = -1
          } else {
            this.fileList.push({
              key,
              Src: reader.result,
              percent: 0,
              status: 'uploading'
            })
          }
          this.$nextTick(() => {
            this.uploadAction(reader.result, file, key)
          })
        }
      }
      this.$refs.uploadInput.value = []
    },
    uploadAction(res, file, key) {
      // const changeIndex = this.fileList.findIndex(item => item.key === key)
      const xhr = new XMLHttpRequest()

      const url = this.action
      xhr.open('POST', url, true)
      xhr.setRequestHeader('Authorization', getToken())
      const formData = new FormData()
      formData.append('files', file)
      formData.append('dir', 'bill')
      xhr.send(formData)
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          const resData = JSON.parse(xhr.response)
          if (resData && resData.IsSuccess) {
            this.$set(
              this.fileList,
              this.fileList.findIndex(item => item.key === key),
              {
                ...this.fileList[
                  this.fileList.findIndex(item => item.key === key)
                ],
                ...resData.Data,
                isImg:
                  ['image/jpeg', 'image/png', 'image/gif', 'image/svg'].indexOf(
                    resData.Data.fileType
                  ) >= 0 || false,
                percent: 100
              }
            )
            setTimeout(() => {
              this.$set(
                this.fileList,
                this.fileList.findIndex(item => item.key === key),
                {
                  ...this.fileList[
                    this.fileList.findIndex(item => item.key === key)
                  ],
                  status: 'success'
                }
              )
              this.$emit('update:data', this.fileList)
            }, 200)
          } else {
            this.$set(
              this.fileList,
              this.fileList.findIndex(item => item.key === key),
              {
                ...this.fileList[
                  this.fileList.findIndex(item => item.key === key)
                ],
                status: 'error'
              }
            )
            this.fileList.splice(
              this.fileList.findIndex(item => item.key === key),
              1
            )
          }
        }
      }
      xhr.onprogress = res => {
        if (res.total && res.loaded) {
          this.$set(
            this.fileList[this.fileList.findIndex(item => item.key === key)],
            'percent',
            (res.loaded / res.total) * 100
          )
        }
      }
    },
    handleRemove(key) {
      this.fileList.splice(this.fileList.findIndex(item => item.key === key), 1)
      this.$emit('update:data', this.fileList)
    },
    handleEdit(key) {
      this.editIndex = this.fileList.findIndex(item => item.key === key)

      this.$refs.uploadInput.click()
    },
    handleMeitu(key) {
      this.$emit('on-meitu', this.fileList.findIndex(item => item.key === key))
    },
    handleAdd() {
      if (!this.disabled) {
        this.editIndex = -1
        this.$refs.uploadInput.click()
      }
    }
  }
}
</script>

<style lang="scss">
.img-uplaod-container {
  .is-disabled {
    position: relative;
    &::after {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      // background: rgba(0,0,0,.1);
      content: '';
      display: block;
      cursor: not-allowed;
    }
  }
  .upload-file {
    margin: 0 10px 10px 0;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    // background: #fff;
    overflow: hidden;
    background-color: #fff;
    border: 1px solid #c0ccda;
    border-radius: 6px;
    box-sizing: border-box;
    position: relative;
    vertical-align: top;
    &:hover {
      .uplaod-action {
        display: flex;
      }
    }
    .uplaod-action {
      position: absolute;
      // top: 0;
      // height: 30px;
      bottom: 0;
      left: 0;
      right: 0;
      background: rgba(0, 0, 0, 0.6);
      display: none;
      justify-content: center;
      align-items: center;
      i {
        color: #fff;
        cursor: pointer;
        margin: 0 5px;
      }
    }
    &.is-success {
      .item-status {
        position: absolute;
        right: -15px;
        top: -6px;
        width: 40px;
        height: 24px;
        background: #13ce66;
        text-align: center;
        transform: rotate(45deg);
        box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);
        & > i {
          font-size: 12px;
          margin-top: 11px;
          color: #fff;
          transform: rotate(-45deg);
        }
      }
    }
    &.uploading {
      &:before {
        display: block;
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.3);
      }
    }
    .upload-progress {
      position: absolute;
      .el-progress__text {
        color: #fff;
        font-size: 16px !important;
      }
    }
    img {
      max-width: 100%;
      max-height: 100%;
      vertical-align: middle;
    }
  }
  .el-upload--picture-card {
    position: relative;
    overflow: hidden;
    .el-icon-plus {
      position: absolute;
      top: 50%;
      left: 50%;
    }
  }
  .upload-input {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: block;
    opacity: 0;
    cursor: pointer;
  }
  .drag-img-list {
    display: inline;
    .ghost {
      position: relative;
      &::after {
        width: 100%;
        height: 100%;
        display: block;
        content: '';
        background: #fbfdff;
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        border: 1px dashed #3bb3c2;
      }
    }
    & > div {
      cursor: move;
    }
  }
}
.viewer-container {
  z-index: 9999 !important;
}
</style>
